#include "VideoSettings.h"
#include <OgreRoot.h>

//-------------------------------------------------------------------------------------
VideoSettings::VideoSettings(void)
{
	mpRenderSystem = 0;
	mVSync = 0;
	mpCurOpenGLSettings = new OpenGLConfig();
	mpXMLManager = new SettingsManager("saves/settings.xml", "settings", true);

	// TODO: if false then error: no OpenGL-render
	findPossibleSettings();

	loadSettings();

	setupDisplay();
	Ogre::Root::getSingleton().setRenderSystem(mpRenderSystem);
	Ogre::Root::getSingleton().saveConfig();
}
//-------------------------------------------------------------------------------------
VideoSettings::~VideoSettings(void)
{
	// Save settings
	mpXMLManager->setSetting("VideoSettings/color", mpCurOpenGLSettings->colorDepth->c_str());
	mpXMLManager->setSetting("VideoSettings/freq", mpCurOpenGLSettings->displayFrequency->c_str());
	mpXMLManager->setSetting("VideoSettings/fsaa", mpCurOpenGLSettings->fsaa->c_str());
	mpXMLManager->setSetting("VideoSettings/res", mpCurOpenGLSettings->resolution->c_str());
	mpXMLManager->setSetting("VideoSettings/fullscreen", mpCurOpenGLSettings->fullscreen->c_str());
	mpXMLManager->setSetting("VideoSettings/vsync", mpCurOpenGLSettings->vsync->c_str());

	delete mpXMLManager;
	delete mpCurOpenGLSettings;
}
//-------------------------------------------------------------------------------------
bool VideoSettings::findPossibleSettings(void)
{
	Ogre::RenderSystemList rsList = Ogre::Root::getSingleton().getAvailableRenderers();
	mpRenderSystem = 0;
	bool found = false;

	// Look for the OpenGL Rendering Subsystem
	for (int i = 0; i < (int)rsList.size(); ++i)
	{
		mpRenderSystem = rsList.at(i);
		Ogre::String rName = mpRenderSystem->getName();
		if (rName.compare("OpenGL Rendering Subsystem") == 0)
		{
			found = true;
			break;
		}
	}
	if (!found) return false;


	Ogre::ConfigOptionMap coMap = mpRenderSystem->getConfigOptions();

	// Get and save possible settings
	for (Ogre::ConfigOptionMap::const_iterator it = coMap.begin(); it != coMap.end(); ++it)
	{
		if (strcmp((*it).first.c_str(), "FSAA") == 0)
		{
			mFSAAList = it->second.possibleValues;
		}
		else if (strcmp((*it).first.c_str(), "VSync") == 0)
		{
			Ogre::StringVector possibleValues = it->second.possibleValues;
			for (int i = 0; i < (int)possibleValues.size(); ++i)
			{
				if (strcmp(possibleValues.at(i).c_str(), "Yes"))
				{
					mVSync = true;
					break;
				}
			}
		}
		else if (strcmp((*it).first.c_str(), "Video Mode") == 0)
		{
			mResolutionList = it->second.possibleValues;
		}
	}

	return true;
}
//-------------------------------------------------------------------------------------
void VideoSettings::loadSettings(void)
{
	// Load Settings
	mpCurOpenGLSettings->colorDepth = CharArrayPtr(new Ogre::String(mpXMLManager->getSetting("VideoSettings/color").c_str()));
	mpCurOpenGLSettings->displayFrequency = CharArrayPtr(new Ogre::String(mpXMLManager->getSetting("VideoSettings/freq").c_str()));
	mpCurOpenGLSettings->fsaa = CharArrayPtr(new Ogre::String(mpXMLManager->getSetting("VideoSettings/fsaa").c_str()));
	mpCurOpenGLSettings->fullscreen = CharArrayPtr(new Ogre::String(mpXMLManager->getSetting("VideoSettings/fullscreen").c_str()));
	mpCurOpenGLSettings->resolution = CharArrayPtr(new Ogre::String(mpXMLManager->getSetting("VideoSettings/res").c_str()));
	mpCurOpenGLSettings->vsync = CharArrayPtr(new Ogre::String(mpXMLManager->getSetting("VideoSettings/vsync").c_str()));


	// Check if settings were loaded correctly
	if (strcmp(mpCurOpenGLSettings->colorDepth->c_str(), "") == 0)
	{
		mpCurOpenGLSettings->colorDepth = CharArrayPtr(new Ogre::String("32"));
	}
	if (strcmp(mpCurOpenGLSettings->displayFrequency->c_str(), "") == 0)
	{
		mpCurOpenGLSettings->displayFrequency = CharArrayPtr(new Ogre::String("60"));
	}
	if (strcmp(mpCurOpenGLSettings->fsaa->c_str(), "") == 0)
	{
		mpCurOpenGLSettings->fsaa = CharArrayPtr(new Ogre::String("0"));
	}
	if (strcmp(mpCurOpenGLSettings->fullscreen->c_str(), "") == 0)
	{
		mpCurOpenGLSettings->fullscreen = CharArrayPtr(new Ogre::String("No"));
	}
	if (strcmp(mpCurOpenGLSettings->resolution->c_str(), "") == 0)
	{
		mpCurOpenGLSettings->resolution = CharArrayPtr(new Ogre::String("800 x 600"));
	}
	if (strcmp(mpCurOpenGLSettings->vsync->c_str(), "") == 0)
	{
		if (mVSync)
		{
			mpCurOpenGLSettings->vsync = CharArrayPtr(new Ogre::String("Yes"));
		}
		else
		{
			mpCurOpenGLSettings->vsync = CharArrayPtr(new Ogre::String("No"));
		}
		
	}
}
//-------------------------------------------------------------------------------------
void VideoSettings::setupDisplay(void)
{
	mpRenderSystem->setConfigOption("Colour Depth", *(mpCurOpenGLSettings->colorDepth));
	mpRenderSystem->setConfigOption("Display Frequency", *(mpCurOpenGLSettings->displayFrequency));
	mpRenderSystem->setConfigOption("Video Mode", *(mpCurOpenGLSettings->resolution));
	mpRenderSystem->setConfigOption("FSAA", *(mpCurOpenGLSettings->fsaa.get()));
	mpRenderSystem->setConfigOption("Full Screen", *(mpCurOpenGLSettings->fullscreen));
	mpRenderSystem->setConfigOption("VSync", *(mpCurOpenGLSettings->vsync));
}
//-------------------------------------------------------------------------------------
void VideoSettings::updateSettings(void)
{
	setupDisplay();
	Ogre::Root::getSingleton().saveConfig();
	Ogre::Root::getSingleton().restoreConfig();
}
//-------------------------------------------------------------------------------------
OpenGLConfig *VideoSettings::getCurOpenGLSettings(void) const
{
	return mpCurOpenGLSettings;
}
//-------------------------------------------------------------------------------------
const Ogre::StringVector VideoSettings::getResolutionList(void) const
{
	return mResolutionList;
}
//-------------------------------------------------------------------------------------
const Ogre::StringVector VideoSettings::getFSAAList(void) const
{
	return mFSAAList;
}
//-------------------------------------------------------------------------------------
bool VideoSettings::getVSync(void) const
{
	return mVSync;
}